package gu.sql2java.relection;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.WildcardType;

import com.google.common.reflect.TypeToken;

/**
 * copy from common-basex 4.4.0<br>
 * 用于生成通配符类型（WildcardType）的抽象工具类，支持上界和下界通配符类型<br>
 * 示例:
 * <pre>
 * WildcardTyper<Number> superWildcardTyper = new WildcardTyper<Number>(false) {};
 * superWildcardTyper.wildcardType ==> ? super Number
 * WildcardTyper<Number> extendsWildcardTyper = new WildcardTyper<Number>(true) {};
 * extendsWildcardTyper.wildcardType ==> ? extends Number
 * </pre>
 * @param <T> 通配符类型中的边界类型参数，决定通配符类型的上下界基础类型
 * @author guyadong
 */
public abstract  class WildcardTyper<T> {
	/** 生成的通配符类型实例，如：? super Number */
	public final WildcardType wildcardType;
	/** 延迟初始化的TypeToken实例，线程安全 */
	private volatile TypeToken<?> token;

	/**
	 * 构造方法，根据subType参数生成对应的通配符类型
	 * 
	 * @param subType 通配符类型方向标识：
	 *               - true：生成上界通配符类型（? extends T）
	 *               - false：生成下界通配符类型（? super T）
	 */
	@SuppressWarnings("serial")
	protected WildcardTyper(boolean subType){
		TypeToken<?> _token;
		// 根据subType选择创建不同通配符类型的TypeToken
		if(subType) {
			// 创建上界通配符类型TypeToken（Class<? extends T>）
			_token = new TypeToken<Class<? extends T>>(getClass()) {};
		}else {
			// 创建下界通配符类型TypeToken（Class<? super T>）
			_token = new TypeToken<Class<? super T>>(getClass()) {};
		}
		// 从ParameterizedType中提取实际的通配符类型参数
		this.wildcardType = (WildcardType) ((ParameterizedType) _token.getType()).getActualTypeArguments()[0];
	}

	/**
	 * 获取与wildcardType对应的TypeToken实例
	 * 
	 * @return 延迟初始化的TypeToken对象，保证线程安全的单例模式
	 */
	public TypeToken<?> getToken() {
		TypeToken<?> _token = this.token;
		if(null == _token){
			// 使用双重检查锁定保证线程安全
			synchronized(wildcardType){
				_token = this.token;
				if(null == _token){
					this.token = _token = TypeToken.of(wildcardType);
				}
			}
		}
		return _token;
	}
    /**
     * 用于生成下界通配符类型 (? super T) 的抽象基类
     */
    public abstract static class SuperOf<T> extends WildcardTyper<T> {
        protected SuperOf() {
            super(false); // 固定调用父类下界构造
        }
    }

    /**
     * 用于生成上界通配符类型 (? extends T) 的抽象基类 
     */
    public abstract static class SubOf<T> extends WildcardTyper<T> {
        protected SubOf() {
            super(true); // 固定调用父类上界构造
        }
    }
}